<template>
  <div id="geometry">
    针对于几何体的一些练习
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
  name: 'geometry',
  data(){
      return{
      }
  },
  methods:{
      test_defineGeometry1(){
         let container = document.getElementById('geometry');
         let scene = new THREE.Scene();
         let defineGeometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
         //类型数组创建顶点数据
         let vertices = new Float32Array([
            0, 0, 0, //顶点1坐标
            50, 0, 0, //顶点2坐标
            0, 100, 0, //顶点3坐标
            0, 0, 0, //顶点4坐标
            0, 0, 100, //顶点5坐标
            50, 0, 0, //顶点6坐标
            ]);
//             let colors = new Float32Array([
//                 1, 0, 0, //顶点1颜色
//                 0, 1, 0, //顶点2颜色
//                 0, 0, 1, //顶点3颜色
//                 1, 1, 0, //顶点4颜色
//                 0, 1, 1, //顶点5颜色
//                 1, 0, 1, //顶点6颜色
// ]);
        let normals = new Float32Array([
            0, 0, 1, //顶点1法向量
            0, 0, 1, //顶点2法向量
            0, 0, 1, //顶点3法向量

            0, 1, 0, //顶点4法向量
            0, 1, 0, //顶点5法向量
            0, 1, 0, //顶点6法向量
        ]);
        // 创建属性缓冲区对象
        //3个为一组，表示一个顶点的xyz坐标
        let attribute = new THREE.BufferAttribute(vertices, 3); 
        //3个为一组，表示一个顶点的颜色
        //let meshColor = new THREE.BufferAttribute(colors,3);
        // 设置几何体attributes属性的位置属性
        defineGeometry.attributes.position = attribute;
        // 设置颜色属性
        //defineGeometry.attributes.color = meshColor;
        defineGeometry.attributes.normal = new THREE.BufferAttribute(normals,3);
        //材质对象
        let material = new THREE.MeshBasicMaterial({
            // vertexColors: THREE.VertexColors, //颜色插值
            color:0x0000ff,
            side: THREE.DoubleSide //两面可见
        }); 
        //网格模型对象Mesh
        var mesh = new THREE.Mesh(defineGeometry, material); 
        scene.add(mesh);
    //     // 点渲染模式
    //    let ponitsMaterial = new THREE.PointsMaterial({
    //       color: 0xff0000,
    //       size: 10.0 //点对象像素尺寸
    //     }); //材质对象
    //    let points = new THREE.Points(defineGeometry, ponitsMaterial); //点模型对象
    //    scene.add(points); //点对象添加到场景中
    //    // 线条渲染模式
    //    let lineMaterial=new THREE.LineBasicMaterial({
    //      color:0x00ff00 //线条颜色
    //     });//材质对象
    //    let line=new THREE.Line(defineGeometry,lineMaterial);//线条模型对象
    //    scene.add(line);//线条对象添加到场景中
        //辅助三维坐标系
        var axisHelper = new THREE.AxesHelper(250);
        scene.add(axisHelper); 
        //点光源
        let point = new THREE.PointLight(0xffffff);
        //点光源位置
        point.position.set(400, 200, 300); 
        //点光源添加到场景中
        scene.add(point); 
        //环境光
        let ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);
        //相机系数设置
        //窗口宽度
        let width = container.clientWidth; 
        //窗口高度
        let height = container.clientHeight; 
        //窗口宽高比
        let k = width / height;
        //三维场景显示范围控制系数，系数越大，显示的范围越大 
        let s = 200; 
        //创建相机对象
        let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(250, 250, 250); //设置相机位置
        camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
        //创建渲染器对象
        let renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height); //设置渲染区域尺寸
        renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
        container.appendChild(renderer.domElement); //插入canvas对象
        function render(){ 
            renderer.render(scene,camera); 
        }
        let controls = new OrbitControls(camera,renderer.domElement);//创建控件对象
        controls.addEventListener('change', render);//监听鼠标、键盘事件 
    },
      test_defineGeometry2(){
         let container = document.getElementById('geometry');
         let scene = new THREE.Scene();
         let defineGeometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
         //类型数组创建顶点数据
         let vertices = new Float32Array([
            0, 0, 0, //顶点1坐标
            80, 0, 0, //顶点2坐标
            80, 80, 0, //顶点3坐标
            0, 80, 0, //顶点4坐标
            ]);
        let normals = new Float32Array([
            0, 0, 1, //顶点1法向量
            0, 0, 1, //顶点2法向量
            0, 0, 1, //顶点3法向量
            0, 0, 1, //顶点4法向量
        ]);
        let attribute = new THREE.BufferAttribute(vertices, 3); 
        defineGeometry.attributes.position = attribute;
        defineGeometry.attributes.normal = new THREE.BufferAttribute(normals,3);
        // Uint16Array类型数组创建顶点索引数据
        let indexes = new Uint16Array([
        // 0对应第1个顶点位置数据、第1个顶点法向量数据
        // 1对应第2个顶点位置数据、第2个顶点法向量数据
        // 索引值3个为一组，表示一个三角形的3个顶点
        0, 1, 2,
        0, 2, 3,
])
// 索引数据赋值给几何体的index属性
defineGeometry.index = new THREE.BufferAttribute(indexes, 1); //1个为一组
        //材质对象
        let material = new THREE.MeshBasicMaterial({
            // vertexColors: THREE.VertexColors, //颜色插值
            color:0x0000ff,
            side: THREE.DoubleSide //两面可见
        }); 
        //网格模型对象Mesh
        var mesh = new THREE.Mesh(defineGeometry, material); 
        scene.add(mesh);
    //     // 点渲染模式
    //    let ponitsMaterial = new THREE.PointsMaterial({
    //       color: 0xff0000,
    //       size: 10.0 //点对象像素尺寸
    //     }); //材质对象
    //    let points = new THREE.Points(defineGeometry, ponitsMaterial); //点模型对象
    //    scene.add(points); //点对象添加到场景中
    //    // 线条渲染模式
    //    let lineMaterial=new THREE.LineBasicMaterial({
    //      color:0x00ff00 //线条颜色
    //     });//材质对象
    //    let line=new THREE.Line(defineGeometry,lineMaterial);//线条模型对象
    //    scene.add(line);//线条对象添加到场景中
        //辅助三维坐标系
        var axisHelper = new THREE.AxesHelper(250);
        scene.add(axisHelper); 
        //点光源
        let point = new THREE.PointLight(0xffffff);
        //点光源位置
        point.position.set(400, 200, 300); 
        //点光源添加到场景中
        scene.add(point); 
        //环境光
        let ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);
        //相机系数设置
        //窗口宽度
        let width = container.clientWidth; 
        //窗口高度
        let height = container.clientHeight; 
        //窗口宽高比
        let k = width / height;
        //三维场景显示范围控制系数，系数越大，显示的范围越大 
        let s = 200; 
        //创建相机对象
        let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(250, 250, 250); //设置相机位置
        camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
        //创建渲染器对象
        let renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height); //设置渲染区域尺寸
        renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
        container.appendChild(renderer.domElement); //插入canvas对象
        function render(){ 
            renderer.render(scene,camera); 
        }
        let controls = new OrbitControls(camera,renderer.domElement);//创建控件对象
        controls.addEventListener('change', render);//监听鼠标、键盘事件 
    },
      test_defineGeometry3(){
          //var geometry = new THREE.Geometry();
      },
      test_defineGeometry4(){

      },
      test_defineGeometry5(){
          
      }
  }, 
  mounted () {
      //该函数通过定义顶点从而自定义几何体，并且定义了各个顶点的颜色和法线（插值现象）
      this.test_defineGeometry1();
      //该函数测试通过顶点索引复用顶点数据
      //this.test_defineGeometry2();
      //threejs几何体API Geometry 的使用
      //和Geometry相关的api好像被移除了，这个可以后面再看
      this.test_defineGeometry3();
      //访问几何体对象本身的数据
      //几何体的伸缩变换，平移变换，旋转变换
 }
}
</script>

<style scope>
#geometry{
     height: 500px;
}
</style>